package com.lm.controller;

import com.meirengu.common.StatusCode;
import com.meirengu.controller.BaseController;
import com.meirengu.model.Result;
import org.apache.commons.lang.exception.ExceptionUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.imageio.ImageIO;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.awt.*;
import java.awt.font.FontRenderContext;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.Random;

@Controller
@RequestMapping("/code")
public class SecCodeController extends BaseController {
    private static final Logger logger = LoggerFactory.getLogger(SecCodeController.class);

    @RequestMapping
    public void generate(HttpServletRequest request, HttpServletResponse response) {
        ByteArrayOutputStream output = new ByteArrayOutputStream();
        String code = drawImg(output);

        HttpSession session = request.getSession();
        session.setAttribute("sessionSecCode", code);
        logger.info("图片验证码code:{}", code);
        try {
            ServletOutputStream out = response.getOutputStream();
            output.writeTo(out);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }


    private String drawImg(ByteArrayOutputStream output) {
        String code = "";
        for (int i = 0; i < 4; i++) {
            code += randomChar();
        }

        int width = 70;
        int height = 25;
        BufferedImage bi = new BufferedImage(width, height, BufferedImage.TYPE_3BYTE_BGR);
        Font font = new Font("Times New Roman", Font.PLAIN, 20);
        Graphics2D g = bi.createGraphics();
        g.setFont(font);
        Color color = new Color(66, 2, 82);
        g.setColor(color);
        g.setBackground(new Color(226, 226, 240));
        g.clearRect(0, 0, width, height);
        FontRenderContext context = g.getFontRenderContext();
        Rectangle2D bounds = font.getStringBounds(code, context);
        double x = (width - bounds.getWidth()) / 2;
        double y = (height - bounds.getHeight()) / 2;
        double ascent = bounds.getY();
        double baseY = y - ascent;
        g.drawString(code, (int) x, (int) baseY);
        g.dispose();
        try {
            ImageIO.write(bi, "jpg", output);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return code;
    }

    private char randomChar() {
        Random r = new Random();
        String s = "ABCDEFGHJKLMNPRSTUVWXYZ0123456789";
        return s.charAt(r.nextInt(s.length()));
    }

    /**
     * 异步验证图片验证码
     *
     * @param code
     * @param request
     * @author zhangyong
     * @date 2015年12月3日
     */
    @RequestMapping(value = "/vcode")
    @ResponseBody
    public Result validateCode(String code, HttpServletRequest request) {
        String sessionCode = (String) request.getSession().getAttribute("sessionSecCode"); // 获取session中的验证码
        logger.info("sessionCode:{}", sessionCode);
        try {
            if (StringUtils.isBlank(code)) {
                return setResult(StatusCode.MISSING_ARGUMENT, null, StatusCode.codeMsgMap.get(StatusCode.MISSING_ARGUMENT));//验证码为空
            } else if (!code.toUpperCase().equals(sessionCode.toUpperCase())) {
                return setResult(StatusCode.SECCODE_IS_ERROR, null, StatusCode.codeMsgMap.get(StatusCode.SECCODE_IS_ERROR));//验证码不正确
            } else {
                request.getSession().removeAttribute("sessionSecCode");//验证完毕，清除session中的验证码
                return setResult(StatusCode.OK, null, StatusCode.codeMsgMap.get(StatusCode.OK));//验证通过
            }
        } catch (Exception e) {
            e.printStackTrace();
            String params = String.format("参数:code:%s", code);
            logger.error("SecCodeController validateCode throws Exceprion :{} happens. params:{}.", ExceptionUtils.getFullStackTrace(e), params);
            return setResult(StatusCode.INTERNAL_SERVER_ERROR, null, StatusCode.codeMsgMap.get(StatusCode.INTERNAL_SERVER_ERROR));
        }
    }
}
